<?php

namespace origin;

/**
 * 公共方法类
 * @author dece <decezz@qq.com>
 */
class Common
{
    /**
     * 数据合并
     * @param  array $ori_arr 要合并的数组模板
     * @param  array $new_arr 要合并的数据配置
     * @return array          合并后的数组
     */
    public static function config_merge( array $ori_arr , array $new_arr )
    {
        return array_merge($ori_arr, array_intersect_key($new_arr, $ori_arr));
    }

    /**
     * 字符集转换成UTF8(字符串自动识别字符集并转换成UTF8)
     * @param  string $str 未知字符集的字符串
     * @return string      UTF8字符集的字符串
     */
    public static function return_utf8( string $str )
    {
        // 识别字符串编码类型
        $encodeing = mb_detect_encoding($str, ['ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5']);
        // 将字符串转换成UTF-8
        return mb_convert_encoding($str, 'UTF-8', $encodeing);
    }

    /**
     * 替换文件字符串
     * @param  array $file          文件路径
     * @param  array $search_arr    要合并的数组模板
     * @param  array $replace_arr   要合并的数据配置
     * @return array                替换后的字符串
     */
    public static function file_str_replace ( string $file , array $search_arr , array $replace_arr )
    {
        // 读取文件中的字符串
        $file_str = file_get_contents($file);
        // 对应的键填入要修改的值
        $replace_arr = array_merge($search_arr, array_intersect_key($replace_arr, $search_arr));
        // 返回替换后的字符串
        return str_replace(array_keys($search_arr), $replace_arr, $file_str);
    }

    /**
     * 全球唯一标识符
     * @param  string   $hyphen 分隔符
     * @return string   $uuid   唯一标识符
     */
    public static function create_guid( $hyphen = true )
    {
        if (function_exists('com_create_guid')) {
            return com_create_guid();
        } else {
            $charid = md5(uniqid(mt_rand(), true));
            if ($hyphen) {
                $hyphen = $hyphen === true ? chr(45) : $hyphen ; // '-'
                $uuid = substr($charid, 0, 8) . $hyphen;
                $uuid .= substr($charid, 8, 4) . $hyphen;
                $uuid .= substr($charid, 12, 4) . $hyphen;
                $uuid .= substr($charid, 16, 4) . $hyphen;
                $uuid .= substr($charid, 20, 12);
            } else {
                $uuid = $charid;
            }
            return $uuid;
        }
    }

    /**
     * 数据字段合并容错方法
     * @param  array    $field    要合并的键
     * @param  array    $array    要合并的值
     */
    public static function array_combine_auto ( $field , $array )
    {
        // 不是数组不能做处理
        if (!is_array($field) || !is_array($array)) {
            return null;
        }
        // 数据的条数
        $count_val = count($array);
        // 字段的条数
        $count_key = count($field);
        // 判断字段数据是否一致
        if ($count_key < $count_val) {
            // 填补空缺字段
            for ($i = 1; $i <= ($count_val - $count_key); $i++) {
                $field['未知字段' . $i] = 'unknown' . $i;
            }
        } elseif ($count_key > $count_val) {
            // 填补空缺值
            $array = array_pad($array, $count_key, '');
        }
        return array_combine($field, $array);
    }

    /**
     * 解压方法
     * @param  string $path      文件路径
     * @param  string $save_path 保存路径
     * @return bool
     */
    public static function unzip ( $path , $save_path )
    {
        // 实例化ZipArchive官方类
        $zip = new \ZipArchive();
        // 打开zip压缩文件
        $open_res = $zip->open($path);
        // 如果能打开则继续
        if ($open_res) {
            // 定义数组
            $name_list = [];
            // 遍历压缩包中文件名
            for ($i = 0; $i < $zip->numFiles; $i++) {
                // 获取文件名称
                $name_list[] = $zip->getNameIndex($i);
            }
            // 提取文件
            $extract_res = $zip->extractTo($save_path);
        }
        // 关闭资源
        $zip->close();
        if ($extract_res) {
            return $name_list;
        }
        return false;
    }

    /**
     * 下载文件
     * @param   string  $file   文件路径
     * @return  void
     */
    public static function download( $file )
    {
        if (file_exists($file)) {
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment;filename = ' . basename($file)); // 下载文件名称
            header('Content-Transfer-Encoding: binary');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check = 0, pre-check = 0');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file));
            ob_clean();
            flush();
            readfile($file);
            exit;
        }
    }

    /**
     * 安全的base64加密
     * @param  string   $string     字符串
     * @param  string   $data       安全加密的字符串
     */
    public static function safe_base64_encode ( $string )
    {
        // base64_encode加密数据
        $data = base64_encode($string);
        // 返回替换后的字符串
        return str_replace(['+', '/', '='], ['-', '_', ''], $data);
    }

    /**
     * 安全的base64解密
     * @param  string   $string     加密的字符串
     * @param  string   $data       安全解密的字符串
     */
    public static function safe_base64_decode ( $string )
    {
        // 替换字符串
        $data = str_replace(['-', '_'], ['+', '/'], $string);
        // 字符长度和4取余
        $mod4 = strlen($data) % 4;
        // 是否存在余数
        if ($mod4) {
            // 存在余数补=
            $data .= substr('====', $mod4);
        }
        // 返回base64解密数据
        return base64_decode($data);
    }

    /**
     * 字符串密钥加密
     * @param  string   $string     加密的字符串
     * @param  string   $secretKey  加密密钥
     */
    public static function password ( $string , $secretKey )
    {
        // 加密字符串
        return md5(md5($string) . $secretKey);
    }

    /**
     * 数据密钥签名
     * @param  array    $params     数据
     * @param  string   $secretKey  加密密钥
     */
    public static function sign ( $params , $secretKey )
    {
        // 参数按键值排序
        ksort($params);
        // 返回签名后的字符串
        return md5(md5(http_build_query($params)) . $secretKey);
    }

    /**
     * 二维数组按照权重排序
     * @param  array    $array      要排序的二维数组
     * @param  string   $weight     权重字段名称
     */
    public static function multisort ( $array , $weight = 'weight' )
    {
        // 按照权重排序
        array_multisort(array_column($array, $weight), SORT_DESC, SORT_NUMERIC, $array);
        // 返回排序结果
        return $array;
    }

    /**
     * 匹配第一次字符串的位置，分割字符串
     * @param  string   $str        字符串
     * @param  string   $needle     分割符
     */
    public function dichotomy_explode ( $str , $needle )
    {
        $seat = stripos($str, $needle);

        $first = substr($str, 0, $seat);

        $last = substr($str, $seat + 1);

        return [$first, $last];
    }
}
